#include <iostream>
using namespace std;

/*
    引用
        引用是变量的别名        引用的地址和指向的地址是相同的
        定义： 类型名 & 引用名 = 变量名;
            int n1 = 89;
            int &b = n1;    //b是n1的别名  b指向n1
        作用：提高程序的运行效率        引用常常使用在函数形参中
            insert_stu(struct student stu);  传值       消耗的内存是2倍的stu (实参和形参)   cpu需要将实参的内容copy到形参中
            insert_stu(struct student &stu); 传引用     消耗的内存是stu                    cpu不需要将实参的内容copy到形参中
        左值和右值：    x = 10;
            左值：持久存在的可以取地址的        x
            右值：临时的不可以取地址的          10
        const修饰的引用-->常引用
            作用：防止引用修改变量值
                const修饰的引用作为函数形参，实参既可以传递左值，也可以传递右值
                如果定义引用指向的是常量，引用必须使用const修饰


*/

// void fun(int &b)        //实参只能传递左值，不能传递右值
void fun(const int &b) // 实参可以传递左值，也可以传递右值
{
    cout << "b = " << b << endl;
}

int main()
{
    int n1 = 89;
    int n2 = 7878;
    char n3[20] = "hello world";

    cout << "指向普通变量的引用" << endl;
    int &b = n1; // b是n1的别名  b指向n1

    cout << "n1 = " << n1 << endl;
    cout << "b = " << b << endl;
    cout << "n1的地址 = " << &n1 << endl;
    cout << " b的地址 = " << &b << endl;

    b = 100;
    cout << "n1 = " << n1 << endl;
    cout << "b = " << b << endl;

    cout << "指向指针的引用" << endl;
    int *p = &n2;
    int *&b2 = p;
    cout << "n2 = " << n2 << endl;
    cout << "p = " << *p << endl;
    cout << "b2 = " << *b2 << endl;
    cout << "n2的指针地址 = " << &n2 << endl;
    cout << "p的指针指向的地址 = " << p << endl;
    cout << "p的指针本身的地址 = " << &p << endl;
    cout << "b2的指针地址 = " << b2 << endl;

    cout << "指向数组的引用" << endl;
    char (&b3)[20] = n3;
    cout << "n3 = " << n3 << endl;
    cout << "b3 = " << b3 << endl;
    cout << "n3[6] =  " << n3[6] << endl;
    cout << "b3[6] =  " << b3[6] << endl;

    cout << "引用的语法：" << endl;
    int n4 = 98;
    int n5 = 88;
    int &b4 = n4;
    cout << "b4 = " << b4 << endl;
    b4 = n5; // n4的值修改成n5的值      不能将b4指向n5
    cout << "b4 = " << b4 << endl;

    int n6 = 99;
    const double PI = 3.14;
    fun(n6);
    fun(n6 + 5);
    fun(n6 + n6);
    const double b5 = PI;
    double b6 = PI;
    cout << "b5 = " << b5 << endl;
    cout << "b6 = " << b6 << endl;

    
    return 0;
}